#include "intelligentscissor.h"

IntelligentScissor::IntelligentScissor()
{
}
IntelligentScissor::~IntelligentScissor()
{
}
void IntelligentScissor::laplacianZeroCrossing(QImage *qin,double *array){
    int rows=qin->height();
    int cols=qin->width();
    in_image=qin;
    int size=rows*cols;
//5x5 first
    double ker[]={0.0,0.0,1.0,0.0,0.0,
                  0.0,1.0,2.0,1.0,0.0,
                  1.0,2.0,-16.0,2.0,1.0,
                  0.0,1.0,2.0,1.0,0.0,
                  0.0,0.0,1.0,0.0,0.0};
    k_rows=5;
    k_cols=5;
    for(int i=0;i<k_rows*k_cols;i++){
        ker[i]=ker[i]*1.0/16.0;
     }
    kernel=ker;

    struct image img_ker5x5=convolve_img(qin);
//now 9x9
    double ker1[]={0.0,1.0,1.0,2.0,2.0,2.0,1.0,1.0,0.0,
                   1.0,2.0,4.0,5.0,5.0,5.0,4.0,2.0,1.0,
                   1.0,4.0,5.0,3.0,0.0,3.0,5.0,4.0,1.0,
                   2.0,5.0,3.0,-12.0,-24.0,-12.0,3.0,5.0,2.0,
                   2.0,5.0,0.0,-24.0,-40.0,-24.0,0.0,5.0,2.0,
                   2.0,5.0,3.0,-12.0,-24.0,-12.0,3.0,5.0,2.0,
                   1.0,4.0,5.0,3.0,0.0,3.0,5.0,4.0,1.0,
                   1.0,2.0,4.0,5.0,5.0,5.0,4.0,2.0,1.0,
                   0.0,1.0,1.0,2.0,2.0,2.0,1.0,1.0,0.0};

    k_rows=9;
    k_cols=9;
    for(int i=0;i<k_rows*k_cols;i++){
        ker1[i]=ker1[i]*1.0/184.0;
     }
    kernel=ker1;
    struct image img_ker9x9=convolve_img(qin);
    struct image img_ker5x5_lapl;
    struct image img_ker9x9_lapl;
    img_ker5x5_lapl.R=new int[size];
    img_ker5x5_lapl.G=new int[size];
    img_ker5x5_lapl.B=new int[size];
    img_ker9x9_lapl.R=new int[size];
    img_ker9x9_lapl.G=new int[size];
    img_ker9x9_lapl.B=new int[size];
    //int *img_ker5x5_fin=new int[size];
    //int *img_ker9x9_fin=new int[size];
    //array=new double[size];
    calculateLZC(img_ker5x5.R,img_ker5x5_lapl.R,rows,cols);
    calculateLZC(img_ker5x5.G,img_ker5x5_lapl.G,rows,cols);
    calculateLZC(img_ker5x5.B,img_ker5x5_lapl.B,rows,cols);
    calculateLZC(img_ker9x9.R,img_ker9x9_lapl.R,rows,cols);
    calculateLZC(img_ker9x9.G,img_ker9x9_lapl.G,rows,cols);
    calculateLZC(img_ker9x9.B,img_ker9x9_lapl.B,rows,cols);

    for (int x=0;x<cols;x++){
        for(int y=0;y<rows;y++){
            array[x+y*cols]=0.45*(int)((img_ker5x5_lapl.R[x+y*cols])|(img_ker5x5_lapl.G[x+y*cols])|(img_ker5x5_lapl.B[x+y*cols]))+0.55*(int)((img_ker9x9_lapl.R[x+y*cols])|(img_ker9x9_lapl.G[x+y*cols])|(img_ker9x9_lapl.B[x+y*cols]));
          //  cout << array[x+y*cols];
        }
        //cout<<endl;
        }
    delete [] img_ker5x5_lapl.R;
    delete [] img_ker5x5_lapl.G;
    delete [] img_ker5x5_lapl.B;
    delete [] img_ker9x9_lapl.R;
    delete [] img_ker9x9_lapl.G;
    delete [] img_ker9x9_lapl.B;
    delete [] img_ker9x9.R;
    delete [] img_ker9x9.G;
    delete [] img_ker9x9.B;
    delete [] img_ker5x5.R;
    delete [] img_ker5x5.G;
    delete [] img_ker5x5.B;

}

void IntelligentScissor::calculateLZC(int *in,int *out,int rows,int cols){
    for (int x=0;x<cols;x++){
        for(int y=0;y<rows;y++){
            int sign=0;
            int flag=0; //0
            if(in[x+y*cols]==0){
                out[x+y*cols]=0;
                continue;
            }
            else {
                if (in[x+y*cols]>0)
                    sign=1; //+ve
                else
                    sign=-1; //-ve
            }
            int neighbours[]={-1,-1,-1,-1}; //x-1,y;x+1,y;x,y-1;x,y+1
            if ((x-1>=0) && (in[(x-1)+y*cols]*sign<0) )
                neighbours[0]=(in[(x-1)+y*cols]>0?in[(x-1)+y*cols]:-1*in[(x-1)+y*cols]);
            if((x+1<cols)&&(in[(x+1)+y*cols]*sign<0) )
                neighbours[1]=(in[(x+1)+y*cols]>0?in[(x+1)+y*cols]:-1*in[(x+1)+y*cols]);
            if((y-1>=0)&&(in[x+(y-1)*cols]*sign<0))
                neighbours[2]=(in[x+(y-1)*cols]>0?in[x+(y-1)*cols]:-1*in[x+(y-1)*cols]);
            if((y+1>=0)&&(in[x+(y+1)*cols]*sign<0) )
                neighbours[3]=(in[x+(y+1)*cols]>0?in[x+(y+1)*cols]:-1*in[x+(y+1)*cols]);
            for(int k=0;k<4;k++){
                if ((flag==0)&&(neighbours[k]>=0)&&(in[x+y*cols]<neighbours[k]))
                    flag=0;
                else
                    flag=1;
            }
            out[x+y*cols]=flag;
        }
    }

}
